-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Erc4626 extension #465
base: main
Are you sure you want to change the base?
Erc4626 extension #465
Conversation
✅ Deploy Preview for contracts-stylus canceled.
|
I just stared this |
I'll convert this to a draft, so that the team does not invest time reviewing a WIP |
@0xNeshi SafeERC20.safeTransferFrom(_asset, caller, address(this), assets); In the Solidity implementation, |
See how VestingWallet handles this |
Should I implement something like mulDiv for U256 MATH? function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256) {
return assets.mulDiv(totalSupply() + 10 ** _decimalsOffset(), totalAssets() + 1, rounding);
}
|
Should I add the security concerns like docs erc4626 |
I think that would be beneficial. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good first draft, but there's still much work to be done before the PR is deemed "ready for review".
@@ -13,6 +13,7 @@ members = [ | |||
"examples/erc1155", | |||
"examples/erc1155-metadata-uri", | |||
"examples/erc1155-supply", | |||
"examples/erc4262", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"examples/erc4262", | |
"examples/erc4626", |
it happens :D
Rename the example directory too
@@ -13,6 +13,7 @@ members = [ | |||
"examples/erc1155", | |||
"examples/erc1155-metadata-uri", | |||
"examples/erc1155-supply", | |||
"examples/erc4262", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the same member to default-members.
sol!( | ||
#[sol(rpc)] | ||
contract Erc4626 { | ||
function asset() public view returns (address); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
format Solidity code
function totalAssets() public view returns (uint256); | ||
function convertToShares(uint256 assets) public view returns (uint256); | ||
function convertToAssets(uint256 shares) public view returns (uint256); | ||
function maxMint(address) public view returns (uint256); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function maxMint(address) public view returns (uint256); | |
function maxMint(address receiver) public view returns (uint256); |
nit: align function signatures - all functions should list the names of their arguments
function redeem(uint256 shares, address receiver) public returns (uint256); | ||
function withdraw(uint256 assets, address receiver) public returns (uint256); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both of these are missing the owner
parameter
|
||
[dependencies] | ||
openzeppelin-stylus.workspace = true | ||
alloy-primitives = { workspace = true, features = ["tiny-keccak"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need the tiny-keccak
feature?
constructor(address asset_) { | ||
(bool success, uint8 assetDecimals) = _tryGetAssetDecimals(); | ||
_underlyingDecimals = success ? assetDecimals : 18; | ||
_asset = asset_; | ||
} | ||
|
||
function _tryGetAssetDecimals() private pure returns (bool ok, uint8 assetDecimals) { | ||
return (true, 0); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bidzyyys @qalisander I think the example should contain the whole logic here:
constructor(IERC20 asset_) {
(bool success, uint8 assetDecimals) = _tryGetAssetDecimals(asset_);
_underlyingDecimals = success ? assetDecimals : 18;
_asset = asset_;
}
/**
* @dev Attempts to fetch the asset decimals. A return value of false indicates that the attempt failed in some way.
*/
function _tryGetAssetDecimals(IERC20 asset_) private view returns (bool ok, uint8 assetDecimals) {
(bool success, bytes memory encodedDecimals) = address(asset_).staticcall(
abi.encodeCall(IERC20Metadata.decimals, ())
);
if (success && encodedDecimals.length >= 32) {
uint256 returnedDecimals = abi.decode(encodedDecimals, (uint256));
if (returnedDecimals <= type(uint8).max) {
return (true, uint8(returnedDecimals));
}
}
return (false, 0);
}
This should also be included in the docs as a note for lib users.
|
||
#[public] | ||
#[inherit(Erc20, Erc20Metadata, Erc4626)] | ||
impl Erc4262xample { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #465 (comment)
|
||
|
||
|
||
#[allow(missing_docs)] | ||
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); | ||
|
||
#[allow(missing_docs)] | ||
event Withdraw(address indexed sender,address indexed receiver,ddress indexed owner,uint256 assets, uint256 shares); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Format the Solidity code.
- Remove unnecessary empty lines
async fn error_when_exceeded_max_redeem( | ||
alice: Account, | ||
bob: Account, | ||
) -> Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implement e2e tests, and ensure they pass successfully.
@@ -0,0 +1,46 @@ | |||
= ERC-4262 | |||
|
|||
https://eips.ethereum.org/EIPS/eip-4626[ERC-4626] is an extension of xref:erc20.adoc[ERC-20] that proposes a standard interface for token vaults. This standard interface can be used by widely different contracts (including lending markets, aggregators, and intrinsically interest bearing tokens), which brings a number of subtleties. Navigating these potential issues is essential to implementing a compliant and composable token vault. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
#[public] | ||
#[inherit(Erc20, Erc20Metadata, Erc4626)] | ||
impl Erc4262xample { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #465 (comment)
type Error: Into<alloc::vec::Vec<u8>>; | ||
|
||
/// Returns the address of the underlying asset that the vault manages. | ||
fn asset(&self) -> Address; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Double check all functions' docs for missing arguments.
- Ensure your docs follow the existing convention, see other contracts for examples.
Resolves #356
PR Checklist